Software transactional memory (STM) is a concurrency control mechanism analogous to database transactions for controlling access to shared memory in concurrent computing. A transaction in the context of transactional memory is a piece of code that executes a series of reads and writes to shared memory. STM is used as an alternative to traditional locking mechanisms. STM allows concurrent programs to be written more simply. A transaction specifies a sequence of code that is supposed to execute as if it were executing in isolation. This illusion of isolation is achieved by fine-grained locking of objects, and by executing in a mode that allows the side-effects of the transaction to be rolled back if the transaction is discovered to be in conflict with some other transaction. We say that a data access is “transacted” if the code generated for that access has been modified to include support for these locking and rollback mechanisms.
Different data accesses are transacted in different ways. For example, the lock that is acquired to synchronize access to a field is found in different ways depending on whether the field is a static (global) field or an instance field of some object. Rollback is enabled differently for local variables of methods than it is for object instance fields.
Some languages have a “safe subset” that omits features that allow type-safety to be violated. The full language will contain some unsafe features, whose improper use may allow type-safety violations. One example of an unsafe feature is pointer arithmetic: the ability to add an integer value to a pointer value, and dereference the resulting pointer value. If the pointer is of a type that points to type T, then whether the result is actually of type T depends on the correctness of the program, not on built-in guarantees of the language compiler and runtime. In the MICROSOFT® Common Language Runtime (CLR), for example, pointers may be “managed” or “unmanaged.” A managed pointer (also called a “byref”) is constant after initialization, and cannot participate in pointer arithmetic, or be cast to/from other types. Unsafe code may create unmanaged pointers, which allow all these operations.
This impacts transactional memory because a program may have a local variable, an instance field of some object o, and a static field, all of type “int,” and create three unmanaged pointers to these three data locations. The type of the resulting pointer is the same in all cases, “int*” (pointer to int). If the code accesses memory via this pointer, we've lost the information necessary to transact this access in the appropriate way, which depends on the target of the pointer value.